﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;

namespace Shake.Framework.Mvc
{
    public static class JavascriptMvcHtmlExtension
    {
        public static IHtmlString Require(this HtmlHelper htmlHelper, string javascriptFileName)
        {
            // TODO:读缓存
            var splits = System.Text.RegularExpressions.Regex.Split(htmlHelper.ViewContext.Controller.ToString(), "Controllers");
            var controllerName = htmlHelper.ViewContext.RouteData.Values["controller"].ToString();
            //var actionName = ViewContext.RouteData.Values["action"];
            var areaName = splits[0].Trim('.');

            string found = null;
            var lookupPaths = LookupSetting();
            var targetName = string.Format("{0}.js", javascriptFileName);
            foreach (var path in lookupPaths)
            {
                var directories = GetDirectories(path, areaName, controllerName);
                foreach (var directory in directories)
                {
                    var colsePath = Path.Combine(directory, controllerName);
                    if (Directory.Exists(colsePath))
                    {
                        var founds = Directory.GetFiles(Path.Combine(directory, controllerName), targetName);
                        if (founds.Length > 0)
                        {
                            found = founds[0];
                            // TODO:写缓存
                            break;
                        }
                    }
                    else
                    {
                        var founds = Directory.GetFiles(directory, targetName, SearchOption.AllDirectories);
                        if (founds.Length > 0)
                        {
                            found = founds[0];
                            // TODO:写缓存
                            break;
                        }
                    }
                }
                if (found != null) break;
            }

            if (found == null)
            {
                var combimePath = string.Join("<br>\r", lookupPaths);
                //throw new FileNotFoundException(string.Format("在以下路径{0}找不到{1}.js", combimePath, javascriptFileName));
                return new HtmlString(string.Empty);
            }
            found = found.Replace(AppDomain.CurrentDomain.BaseDirectory, string.Empty).Replace("\\", "/");

            //HtmlString result = new HtmlString(string.Format("<script data-main=\"/{0}\"  src=\"/public/libs/require.js\"></script>", found));
            HtmlString result = new HtmlString(string.Format("<script  src=\"/public/libs/require.js\" data-main=\"/{0}\" ></script>", found));
            return result;
        }

        /// <summary>
        /// 查找路径设置,按顺序列表
        /// </summary>
        /// <returns></returns>
        public static List<string> LookupSetting()
        {
            var lookupPaths = new List<string>
            {
                "Plugins/{AreaName}/Public/{ControllerName}",
                "Plugins/*/Public", // 不要以/开头或结尾，不要以*结尾
                "Public",
            };
            return lookupPaths;
        }

        private static List<string> GetDirectories(string search, string areaName, string controllerName)
        {
            var directories = new List<string> { AppDomain.CurrentDomain.BaseDirectory };

            var splits = search.Replace("{AreaName}", areaName).Replace("{ControllerName}", controllerName).Split('/');
            foreach (var split in splits)
            {
                if (string.Equals(split, "*"))
                {
                    foreach (var directory in directories)
                    {
                        directories = Directory.GetDirectories(directory).ToList();
                    }
                }
                else
                {
                    var TemporaryDirectories = new List<string>();
                    foreach (var directory in directories)
                    {
                        var path = Path.Combine(directory, split);
                        if (Directory.Exists(path))
                        {
                            TemporaryDirectories.Add(path);
                        }
                    }
                    directories.Clear();
                    directories.AddRange(TemporaryDirectories);
                }
            }
            return directories;
        }
    }
}
